<!DOCTYPE html>
<!--[if lt IE 7 ]> <html class="ie6"> <![endif]-->
<!--[if IE 7 ]>    <html class="ie7"> <![endif]-->
<!--[if IE 8 ]>    <html class="ie8"> <![endif]-->
<!--[if IE 9 ]>    <html class="ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html class=""> <!--<![endif]-->
<head>
    <title>Grails - Plugin - Apache Shiro Integration for Grails</title>

    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <meta name="robots" content="NOODP">
    <meta name="Description" content="Grails is a high-productivity web framework based on the Groovy language that embraces the coding by convention paradigm, but is designed specifically for the Java platform.">	

    
    <link href="/static/mnqzhxEka8fg6Hu3z6ra5TBwnHBXIJDpqN0Mz2O4JZw.ico" rel="shortcut icon" />
    <script src="/static/olHYw9s4sRWKtAqM0Gycx7M0Zi61vStT4U3dxxe4zR.js" type="text/javascript" ></script>
<script src="/static/SMqIhZQnW0hVcv1ddCsxzQAJ71v52rNDzHCwyhS4NHM.js" type="text/javascript" ></script>
<script src="/static/zJHP5VyHm7tL27vEElZXfjJUO9IWNUqhzUqJ7jXFex1.js" type="text/javascript" ></script>
<script src="/static/PXn7laUPGOsQB6caqG8xV2fUb6XyaPMIkosH6okdOTD.js" type="text/javascript" ></script>
<script src="/static/nIDw1ClETEFYILk6AqTiR5bBWvrsl4irOGodj5WxsXr.js" type="text/javascript" ></script>
<link href="/static/lnLhuvgzxCZaUwFqFGrwOCnzFQoTAPmAdvqwKmkYq5t.css" type="text/css" rel="stylesheet" media="screen, projection" />
<script src="/static/dg9ioT1XCL1ZJ0fVbSfDWQXU6ASGLxG6QzSrJVXaVgK.js" type="text/javascript" ></script>
<link href="/static/Opg3Oryy8VpgNOpsxQxelNsG6mWJ5MaPX6gZBB8NMYZ.css" type="text/css" rel="stylesheet" media="screen, projection" />
<link href="/static/fvo8UjifhHvTL121bHsTKOhZeKDh9S4bcsV6XNkOHHv.css" type="text/css" rel="stylesheet" media="screen, projection" />
<script src="/static/YcSNCmz8BrISJAxiTyEkdATtlGLFI99Wxo2Pa9L13Kl.js" type="text/javascript" ></script>
<script src="/static/YHG3gHOpS8TE7QVrjOuyX6uUlqsYPwB9kQrSFEsxD7a.js" type="text/javascript" ></script>
<link href="/static/o4wHGtUOHXBJuPyrsvYpzLuyUxHUfStG072sW4bJVOl.css" type="text/css" rel="stylesheet" media="screen, projection" />
<link href="/static/TOJMZzFaJFbeJVXl1XwpqyLonNPdeGS5a8VONNFESsp.css" type="text/css" rel="stylesheet" media="screen, projection" />
<script src="/static/BShzjOAQ87uh6fYS63tFPd3kbCSl7rqPY1YehfqiRT.js" type="text/javascript" ></script>
<link href="/static/kWsg6T4w4nTwYkIfUHB7IHizfKyfnvLTxfu5eCnirze.css" type="text/css" rel="stylesheet" media="screen, projection" />
<script src="/static/M0DhE7Mwi8RtwdRel3GBRmZA7IygSwum6SVMAJDtBFW.js" type="text/javascript" ></script>
<script src="/static/PK5vLlWR0gVPQOTahgPgD5qKjpbazdrmuI6aFfhEE9.js" type="text/javascript" ></script>
<link href="/static/HmYhiMCDWqs72fUqsJyQx0ssScRkoSFLrSIG6LyBFJK.css" type="text/css" rel="stylesheet" media="screen, projection" />
<script src="/static/O3ToRxl9lcGuBkdVGKkTvEHpRD465kZYk2Hmu0dpgex.js" type="text/javascript" ></script>
<link href="/static/oJi67HlPQg1wH3AWLXOw37JOhZ4DvaObfmcQjDzaC5Q.css" type="text/css" rel="stylesheet" media="screen, projection" />
<script src="/static/A9S42WFGksTUJWihLBxBNwwMHWyMp5ti18HnZqmgDmT.js" type="text/javascript" ></script>

<link href="/static/bqYjrlbrS9BWb7TGvdlu6qxiUY1we21Ex38KeByXnEb.css" type="text/css" rel="stylesheet" media="screen, projection" />
<link href="/static/CEOe0gYZxFeVl9Ia3plLhwZsqwIcL1qzKT4MU1oQnun.css" type="text/css" rel="stylesheet" media="screen, projection" />
<script src="/static/Usluy7PoBn83Rbmazshp3eeoE6ViaO3vGgzUdMZdrRA.js" type="text/javascript" ></script>
<link href="/static/qOHdlDQShC0snzJ3RY1d8K0tmb410w7KZ94t6rSKO6p.css" type="text/css" rel="stylesheet" media="screen, projection" />
<link href="/static/zGiUdmUmL31K5Uirie6Jp1ERQc2U9tjc2OzS22SSDEx.css" type="text/css" rel="stylesheet" media="screen, projection" />




    
    
    
    
        
    
    
    
    

    

    
    
    

    
    <meta name="layout" content="pluginDetails">


    
    

    <style type="text/css" media="screen">
.yui-navset-bottom .yui-nav li a em {
    display:inline;
}
.yui-navset .yui-nav li a em, .yui-navset-top .yui-nav li a em, .yui-navset-bottom .yui-nav li a em {
    display:inline;
}
    </style>


    


</head>
<body onload="addJsClass();">
    
    <div id="header" align="center">
        <div id="springSourceBar">
	<div id="grailsLogo">
		<a href="/"><img src="/static/cXmUZIAv28XIiNgkRiz4RRl21TsGZ5HoGpZw1UITNyV.png" border="0" /></a>			
	</div>

	<div id="springSourceLogo">
		<a href="http://www.springsource.com/"><img src="/static/xATgakdqUqjehM4CPEgEyIEVaa7xHY09sonkDDDBPA5.png" border="0" /></a>			
	</div>
	<div id="searchbar">
		<form action="/search" method="get" name="searchForm" id="searchForm" >
		    <input
		 		onblur="this.style.color = '#CDE5C4';" 
				onfocus="this.style.color = '#48802C';this.value='';"
				type="text" accessKey="s" name="q" value=""/>		
		</form>		
	</div>
</div>

        <div class="mainMenuBarWrapper">
            <ul id="mainMenuBar">
	
    <li><a href="http://www.springsource.com/products/grails">Products</a></li>
    <li><a href="http://www.springsource.com/groovy-grails-consulting">Services</a></li>
    <li><a href="http://www.springsource.com/training/grv001">Training</a></li>
    <li><a href="/Testimonials">Case Studies</a></li>
    <li><a href="/Community">Community</a></li>
    <li><a href="/Download">Downloads</a></li>
    <li><a href="/plugins">Plugins</a> </li>
    <li><a href="/Documentation">Documentation</a></li>
</ul><!-- mainMenuBar -->

        </div>
    </div>

    <div id="contentWrapper" align="center">
        <div id="contentInnerWrapper">
            <div id="contentCenter" >
                
    

    <div id="contentPane">

	<div id="pluginBigBox">
            
		
            <div id="pluginBgTop"></div>
            <div id="pluginBox">
                <div id="pluginDetailWrapper">

                    
    <div id="pluginDetailsBox">
        <div id="pluginDetailsTop"></div>
        <div id="pluginDetailsContainer">
            
            
            
        <div class="null">
            <div id="loginDialog">
                <div class="hd">Login required</div>
                <div class="bd">
                    
                <div id='loginFormDiv'></div>
            
                </div>
            </div>
        </div>
        <script>
            function init_dlg_loginDialog() {
                // Instantiate the Dialog
                GRAILSUI.loginDialog = new YAHOO.widget.Dialog("loginDialog",
                { 'modal': true,
'fixedcenter': true,
'visible': false,
'params': [],
'constraintoviewport': true,
'buttons': [{'text': 'OK',
handler: function() {this.cancel();},
'isDefault': true}] });
                GRAILSUI.loginDialog.render(document.body);
                
        
            }
            YAHOO.util.Event.onDOMReady(init_dlg_loginDialog);
        </script>

            <div id="downloadBox">
                <a href="http://plugins.grails.org/grails-shiro/tags/RELEASE_1_1_1/grails-shiro-1.1.1.zip"><img src="/static/OPPwb7Wv8IXVwcl47IOpipg9CwS65FWrxQSXQVVmAVh.png" alt="Download" border="0" /></a>
            </div>

            <h1 id="pluginBoxTitle">Apache Shiro Integration for Grails</h1>

            <div class="ratingBox">
                
                
                    <div id="ratingDisplay">
                        
            <table class="ratingDisplay">
                <tr>
            <td><div class="star on"><a href="/login?originalURI=%2Fplugin%2Fshiro"></a></div></td><td><div class="star on"><a href="/login?originalURI=%2Fplugin%2Fshiro"></a></div></td><td><div class="star on"><a href="/login?originalURI=%2Fplugin%2Fshiro"></a></div></td><td><div class="star on"><a href="/login?originalURI=%2Fplugin%2Fshiro"></a></div></td><td><div class="star on"><a href="/login?originalURI=%2Fplugin%2Fshiro" style="width:7.692299999999985%"></a></div></td>
                    <td>(26)</td>
                </tr>
            </table>
                                                                                                        
                    </div>
                
            </div>
            <div class="pluginDetail">
                
                <div class="pluginUsage">
                    <div>Used by approximately</div>
                    <div class="value">2%</div>
                    <div>of Grails users</div>
                </div>
                
                <table>
                    <tr>
                        <th>Author(s)</th>
                        <td>Peter Ledbrook</td>
                    </tr>
                    <tr>
                        <th>Current Release</th>
                        <td>1.1.3&nbsp;&nbsp;&nbsp;(1 year ago)</td>
                    </tr>
                    <tr>
                        <th>Grails Version</th>
                        <td>1.1 &gt; *</td>
                    </tr>
                    
                    
                    <tr>
                        <th>Tags</th>
                        <td class='tags'>
                            <span id='pluginTags'>
                                

    <span class="tag"><a href="/plugins/tag/security">security</a>&nbsp;
    
        

        
        
        
        
            <img id="remove_security_tag_from_500" src="/static/ZkvUw6b7PrI8Pma3KmlIB2A1CSEDHmmf0sJQq3h9vSf.png"/>
            <script>
                YAHOO.util.Event.onDOMReady(function() {
                    // on show, put the dialog in the right place
                    YAHOO.util.Event.on("remove_security_tag_from_500", 'click', function() {
                        window.location = "/login?originalURI=%2Fplugin%2Fshiro";
                    });
                });
            </script>
        
    
    </span>


                            </span>
                            <span id='addTagTrigger'><img src="/static/V6lM9VtbWbu4xVIRmbEy9b9fLKlnbnjkdqYpgr9UUla.png" /></span>
                        </td>
                    </tr>
                    <tr>
                        <th>Dependency</th>
                        <td><pre>compile ":shiro:1.1.3"</pre></td>
                    </tr>
                    
                </table>
            </div>
            <ul class="links">
                
<li><a href="http://github.com/pledbrook/grails-shiro"> <img src="/static/trqEoCdSJ5w3ZFEEbpY0HWoHsc8unKTBKpdx8nJJdjU.png" border="0" />&nbsp;Source</a></li>


<li><a href="http://grails.org/plugin/shiro"> <img src="/static/p0JQdku750CsGnqCBsMCxTgbSRcQNFWPoc1ysZ5LFuf.png" border="0" />&nbsp;Docs</a></li>


  <li><a href="http://jira.grails.org/browse/GPSHIRO"><img src="/static/IIi3GU4zjZntKH4h6mwqDnpGWcB6zCNQyt6r3UowNMO.png" border="0" />&nbsp;Issues</a></li>


                <li>
                    <a href="/plugin/edit/500">
                        <img src="/static/drgakn823IcL4KeSlqigXNEYTBqSs0AKbVKJQH1z1yl.png" border="0" />&nbsp;Edit Plugin
                    </a>
                </li>
            </ul>
        </div>

        <div class="description">
            Enables Grails applications to take advantage of the Apache Shiro security layer. Adapted from previous JSecurity plugin.
        </div>
        
    </div>

    
</div>



    
    
    
    
        <script>
            YAHOO.util.Event.onDOMReady(function() {
                // on show, put the dialog in the right place
                YAHOO.util.Event.on('addTagTrigger', 'click', function() {
                    window.location = "/login?originalURI=%2Fplugin%2Fshiro";
                });
                // also hang up rating click if not logged in, redirect to login page with originalURI of this page
                // for redirect
                YAHOO.util.Event.on('ratingdiv', 'click', function(e) {
                    YAHOO.util.Event.stopEvent(e);
                    window.location = "/login?originalURI=%2Fplugin%2Fshiro";
                });
            });
        </script>
    

    <div id="pluginContent">
        
            
        <div id="tabView_gui_fa6cc9bc44379aba5dc805b1baf53e87" class="yui-navset">
            <div class="tabOuter">
                <div class="tabInner">
                    <ul class="yui-nav">
                        <li class='  '><a href="#installationTab"><span class="tabLeft"></span><em>Installation</em><span class="tabRight"></span></a></li>

<li class='selected  '><a href="#descriptionTab"><span class="tabLeft"></span><em>Description</em><span class="tabRight"></span></a></li>

<li class='  '><a href="#faqTab"><span class="tabLeft"></span><em>Faq</em><span class="tabRight"></span></a></li>

<li class='  '><a href="#screenshotsTab"><span class="tabLeft"></span><em>Screenshots</em><span class="tabRight"></span></a></li>

                    </ul>
                </div><!-- end #tabInner -->
            </div><!-- end #tabOuter -->
            <div class="yui-content">
                <div id="installationTab">
                        



<div id="wikiLastUpdated">Last updated by pledbrook 2 years ago</div>
<div id="viewLinks" class="wikiLinks">
    

    <ul class="wikiActionMenu">
        
            <li>
                <a href="/plugin/installation-500/editWikiPage/installationTab" onclick="YAHOO.util.Connect.asyncRequest('GET', '/plugin/installation-500/editWikiPage/installationTab', {success: function(o){hideCommentPost();YAHOO.util.Dom.get('installationTab').innerHTML = o.responseText;}, failure: function(o){}}, null);return false;" class="actionIcon" action="editWikiPage" id="installation-500">
                    <img src="/static/drgakn823IcL4KeSlqigXNEYTBqSs0AKbVKJQH1z1yl.png" border="0" width="15" height="15" alt="Icon Edit" class="inlineIcon" />
                    <span>Edit</span>
                </a>
            </li>
        
        <li>
            <a href="/plugin/installation-500/infoWikiPage/installationTab" onclick="YAHOO.util.Connect.asyncRequest('GET', '/plugin/installation-500/infoWikiPage/installationTab', {success: function(o){YAHOO.util.Dom.get('installationTab').innerHTML = o.responseText;}, failure: function(o){}}, null);return false;" class="actionIcon" action="infoWikiPage" id="installation-500">
                <img src="/static/PnoLmQ9FQkQ1vYUqZ6BJ5yWRWKMaUJOz3Hzx68S9YBq.png" border="0" width="15" height="15" alt="Icon Edit" class="inlineIcon" />
                <span>View Info</span>
            </a>
        </li>
    </ul>
</div>






Simply execute
<div class="code"><pre>grails install&#45;plugin shiro</pre></div>
This will install the plugin and create a  <code>grails-app/realms</code>  directory. Your application won't be immediately protected, but that is easily rectified: just read the quick start on the description tab.
<script type="text/javascript">
   if(myYUI.get('message')!=null) {
        myYUI.fade('message', {delay:3});
   }
</script>

                    </div>

<div id="descriptionTab">
                        



<div id="wikiLastUpdated">Last updated by suryazi 1 month ago</div>
<div id="viewLinks" class="wikiLinks">
    

    <ul class="wikiActionMenu">
        
            <li>
                <a href="/plugin/description-500/editWikiPage/descriptionTab" onclick="YAHOO.util.Connect.asyncRequest('GET', '/plugin/description-500/editWikiPage/descriptionTab', {success: function(o){hideCommentPost();YAHOO.util.Dom.get('descriptionTab').innerHTML = o.responseText;}, failure: function(o){}}, null);return false;" class="actionIcon" action="editWikiPage" id="description-500">
                    <img src="/static/drgakn823IcL4KeSlqigXNEYTBqSs0AKbVKJQH1z1yl.png" border="0" width="15" height="15" alt="Icon Edit" class="inlineIcon" />
                    <span>Edit</span>
                </a>
            </li>
        
        <li>
            <a href="/plugin/description-500/infoWikiPage/descriptionTab" onclick="YAHOO.util.Connect.asyncRequest('GET', '/plugin/description-500/infoWikiPage/descriptionTab', {success: function(o){YAHOO.util.Dom.get('descriptionTab').innerHTML = o.responseText;}, failure: function(o){}}, null);return false;" class="actionIcon" action="infoWikiPage" id="description-500">
                <img src="/static/PnoLmQ9FQkQ1vYUqZ6BJ5yWRWKMaUJOz3Hzx68S9YBq.png" border="0" width="15" height="15" alt="Icon Edit" class="inlineIcon" />
                <span>View Info</span>
            </a>
        </li>
    </ul>
</div>






Secure your Grails application quickly and easily using the <a href="http://shiro.apache.org" target="blank">Apache Shiro</a> security framework. Although easy to get started with, this framework gives you a great deal of flexibility and will support your application as it grows.<p class="paragraph"/>To find out what's new with each version of the plugin, check out the <a href="http://grails.org/Shiro+Release+Notes" class="pageLink">release notes</a>.<p class="paragraph"/><a name="Quick Start"></a><h1>Quick Start</h1><p class="paragraph"/>Installing the plugin is only the first step to securing your application. It tries not to force a security model upon you, so you have to create your own. Fortunately, it's easy to set up a model that will satisfy the vast majority of user requirements. This is your one-stop-shop command to get yourself up and running:
<div class="code"><pre>grails shiro&#45;quick&#45;start</pre></div><p class="paragraph"/>The shiro-quick-start command takes a 'prefix' argument: 
<div class="code"><pre>grails shiro&#45;quick&#45;start &#45;&#45;prefix=org.example.</pre></div>
This will create org.example.User and org.example.Role classes. If you want to include a package <strong class="bold">and</strong> the 'Shiro' prefix, just specify --prefix=org.example.Shiro<p class="paragraph"/>This will create a  <code>ShiroDbRealm</code>  class under  <code>grails-app/realms</code>  and also some related domain classes, which you can distinguish by their "Shiro" prefix. The realm is the repository of access control information; it decides whether a particular user has the rights to do something.<p class="paragraph"/>The above command also creates a controller,  <code>grails-app/controllers/AuthController.groovy</code> , that provides a login screen, an action for signing into the application, and another one for signing out.<p class="paragraph"/>Finally, it create a Grails filters class,  <code>grails-app/conf/SecurityFilters.groovy</code> , that enables access control on all your controllers and actions. Try it out! When you attempt to navigate to one of your controller pages, you will be redirected to a login screen. Of course, there are no users in the system yet, so you can't successfully log in. Let's rectify that now by adding an example user to the application in  <code>grails-app/conf/BootStrap.groovy</code> :
<div class="code"><pre><span class="java&#45;keyword">import</span> org.apache.shiro.crypto.hash.Sha256Hash<p class="paragraph"/>class BootStrap &#123;<p class="paragraph"/>    def init = &#123; servletContext &#45;&#62;
        def user = <span class="java&#45;keyword">new</span> ShiroUser(username: <span class="java&#45;quote">"user123"</span>, passwordHash: <span class="java&#45;keyword">new</span> Sha256Hash(<span class="java&#45;quote">"password"</span>).toHex())
        user.addToPermissions(<span class="java&#45;quote">"&#42;:&#42;"</span>)
        user.save()
    &#125;<p class="paragraph"/>    def destroy = &#123;
    &#125;
&#125;</pre></div>
The above code will create a user  <code>user123</code>  that can access all controller actions. You can add as many or as few users as you like in the same way.<p class="paragraph"/>Your application is now secure!<p class="paragraph"/><a name="Fine-tuning the access control"></a><h1>Fine-tuning the access control</h1><p class="paragraph"/>The default Shiro setup provided by the  <code>shiro-quick-start</code>  command is very flexible and powerful. It's based on permission strings known as "wildcard permissions" that are simple to use, but in some ways difficult to understand because they are also very flexible.<p class="paragraph"/><a name="About wildcard permissions"></a><h2>About wildcard permissions</h2><p class="paragraph"/>Let's start with an example. Say you want to protect access to your company's printers such that some people can print to particular printers, while others can find out what jobs are currently in the queue. The basic type of permission is therefore "printer", while we have two sub-types: "query" and "print". We also want to restrict access on a per-printer basis, so we then have a second sub-type that is the printer name. In wildcard permission format, the permission requirements are
<div class="code"><pre>printer:query:lp7200
printer:print:epsoncolor</pre></div>Notice how each part is separated by a colon? That's how the wildcard permission format separates what it calls "parts". It's also worth pointing out at this stage that Apache Shiro has no understanding of printer permissions - they are used and interpreted by the application.<p class="paragraph"/>So those are permission requirements. They state what permission is required to do something. In the above example, the first permission says that a user must have the right to query the "lp7200" printer. That's just the application's interpretation of the string, though. You still need to code the permission requirement into your application. A simple way to do this is in a condition:
<div class="code"><pre><span class="java&#45;keyword">if</span> (SecurityUtils.subject.isPermitted(<span class="java&#45;quote">"printer:query:lp7200"</span>)) &#123;
    // Return the current jobs on printer lp7200
&#125;</pre></div>On the other side of the coin, you have permission assignments where you say what rights particular users have. In the quick start example, you saw a permission assignment in the  <code>BootStrap</code>  class.<p class="paragraph"/>Assignments look a lot like permission requirements, but they also support syntax for wildcards and specifying multiple types or sub-types. What do I mean by that? Well, imagine you want a user to have print access to all the printers in a company. You could assign all the permissions manually:
<div class="code"><pre>printer:print:lp7200
printer:print:epsoncolor
...</pre></div>but this doesn't scale well, particularly when new printers are added. You can instead use a wildcard:
<div class="code"><pre>printer:print:&#42;</pre></div>This does scale, because it covers any new printers as well. You could even allow access to all actions on all printers:
<div class="code"><pre>printer:&#42;:&#42;</pre></div>or all actions on a single printer:
<div class="code"><pre>printer:&#42;:lp7200</pre></div>or even specific actions:
<div class="code"><pre>printer:query,print:lp7200</pre></div>The '*' wildcard and ',' sub-type separator can be used in any part of the permission, even the first part as you saw in the  <code>BootStrap</code>  example.<p class="paragraph"/>One final thing to note about permission assignments: missing parts imply that the user has access to all values corresponding to that part. In other words,
<div class="code"><pre>printer:print</pre></div>is equivalent to<p class="paragraph"/><div class="code"><pre>printer:print:&#42;</pre></div>and<p class="paragraph"/><div class="code"><pre>printer</pre></div>is equivalent to<p class="paragraph"/><div class="code"><pre>printer:&#42;:&#42;</pre></div>However, you can only leave off parts from the end of the string, so this:<p class="paragraph"/><div class="code"><pre>printer:lp7200</pre></div>is <strong class="bold">not</strong> equivalent to<p class="paragraph"/><div class="code"><pre>printer:&#42;:lp7200</pre></div><p class="paragraph"/>Permission assignments like these are typically done at the database level, although it depends on your realm implementation. With the default realm installed by  <code>quick-start</code>  you can assign permissions directly to users or via roles.<p class="paragraph"/><a name="Of users, roles, and permissions"></a><h2>Of users, roles, and permissions</h2><p class="paragraph"/>When you run  <code>quick-start</code> , it creates a realm under  <code>grails-app/realms</code>  and domain classes representing a user and a role.<p class="paragraph"/>You can probably guess what the user domain class is for: it represents the user that logs into your application, hence why it contains a username and a password hash. It stores a hash of the password so that even if someone hacks into the database and gets the user details, he or she can't log in as that user. So how does the application check whether a user has entered the correct password for a given username?<p class="paragraph"/>Your application should at this point have an  <code>AuthController</code>  under  <code>grails-app/controllers</code> . This has a  <code>signIn</code>  action that logs a user into the application via  <code>SecurityUtils.subject.login(authToken)</code> . When that  <code>login()</code>  method is called, a request is made to all the realms that support the particular type of authentication token (usually a  <code>UsernamePasswordToken</code> ) to check whether the credentials (the password in this case) match those stored by the realm.<p class="paragraph"/>The default realm basically hashes the password provided in the authentication token using SHA256 and then compares the hash to the password hash stored in the user domain instance. If the hashes are the same, the user is authenticated. Now, SHA256 has known vulnerabilities, so you may want to use something a little more secure. If that's the case, you need to do two things. First, when you create a user (such as in  <code>BootStrap</code> ) you need to hash the password using the alternative algorithm, for example:
<div class="code"><pre><span class="java&#45;keyword">import</span> org.apache.shiro.crypto.hash.Sha512Hash
&#8230;
    def user = <span class="java&#45;keyword">new</span> ShiroUser(username: <span class="java&#45;quote">"user123"</span>, passwordHash: <span class="java&#45;keyword">new</span> Sha512Hash(<span class="java&#45;quote">"password"</span>).toHex())
    user.save()</pre></div>
Second, you need to override the  <code>credentialMatcher</code>  bean, for example by adding the following to your  <code>grails-app/conf/spring/resources.groovy</code>  file:
<div class="code"><pre><span class="java&#45;keyword">import</span> org.apache.shiro.authc.credential.Sha512CredentialsMatcher<p class="paragraph"/>beans = &#123;
    credentialMatcher(Sha512CredentialsMatcher) &#123;
        storedCredentialsHexEncoded = <span class="java&#45;keyword">true</span>
    &#125;
    &#8230;
&#125;</pre></div>
Make sure that your credentials matcher is configured for hex-encoded passwords if you store hex-encoded hashes in your user domain objects. Also beware that the bean name is  <code>credentialMatcher</code>  (no 's'), whereas there is an 's' in the names of the matcher classes.<p class="paragraph"/>The other domain class of interest is  <code>ShiroRole</code> . Roles are basically a name, such as "Administrator" or "Guest" that can be assigned to a user. The default realm allows users to have multiple roles. One approach to security is to simply check whether a user has a particular role, for example via  <code>SecurityUtils.subject.hasRole(roleName)</code> . Although simple, this approach fails to scale well and makes life more complicated as application requirements evolve. A far better way of using roles is to assign permissions to them:
<div class="code"><pre>def adminRole = <span class="java&#45;keyword">new</span> ShiroRole(name: <span class="java&#45;quote">"Administrator"</span>)
adminRole.addToPermissions(<span class="java&#45;quote">"printer:&#42;:&#42;"</span>)
adminRole.addToPermissions(<span class="java&#45;quote">"admin"</span>)
&#8230;
adminRole.save()</pre></div>When you assign such a role to a user, the user automatically gains all those permissions assigned to the role:
<div class="code"><pre>user.addToRoles(adminRole)
user.save()
// 'user' now has all administrator rights</pre></div>It's then very easy to grant and revoke access rights to and from roles and the changes immediately apply to all users with the affected role(s). Very powerful and surprisingly easy.<p class="paragraph"/>You can even modify the rights for an individual by assigning permissions directly to users:
<div class="code"><pre>user.addToPermissions(<span class="java&#45;quote">"printer:print:lp7200,epsoncolor"</span>)
user.save()</pre></div>There's only one more thing to say about users, roles, and permissions. Although  <code>quick-start</code>  creates the domain classes and realm with a "Shiro" prefix, you can change that by passing a  <code>&#45;&#45;prefix</code>  argument to the command:
<div class="code"><pre>grails quick&#45;start &#45;&#45;prefix=<span class="java&#45;quote">"Sec"</span></pre></div>For non-Windows users, you can even pass an empty string as the prefix, so you end up with the domain classes  <code>User</code>  and  <code>Role</code> . Windows users are currently affected by a bug that means an empty string cannot be passed as an argument.<p class="paragraph"/>Once you have set up your permission assignments, your thoughts might turn to how you can protect your application's URLs. Not to worry, they're already protected if you've used  <code>quick-start</code> !<p class="paragraph"/><a name="Access control by convention"></a><h2>Access control by convention</h2><p class="paragraph"/>The plugin enables access control via standard Grails filters. In fact, the  <code>quick-start</code>  command created one for you: see  <code>grails-app/conf/SecurityFilters.groovy</code> . It's contents will look something like this:
<div class="code"><pre>class SecurityFilters &#123;
    def filters = &#123;
        all(uri: <span class="java&#45;quote">"/&#42;&#42;"</span>) &#123;
            before = &#123;
                // Ignore direct views (e.g. the <span class="java&#45;keyword">default</span> main index page).
                <span class="java&#45;keyword">if</span> (!controllerName) <span class="java&#45;keyword">return</span> <span class="java&#45;keyword">true</span><p class="paragraph"/>                // Access control by convention.
                accessControl()
            &#125;
        &#125;
    &#125;
&#125;</pre></div>This adds a before interceptor to all URLs. Don't worry too much about the first part of the interceptor - it's there to exclude the default home page from being protected. You can remove it if you like. The more important bit is the  <code>accessControl()</code>  method call. This one line automatically protects all your controller actions by implicitly adding a permission requirement to each one.<p class="paragraph"/>For example, say you have a scaffolded  <code>BookController</code> . A user can only access an action of that controller if he or she has the corresponding permission of the form  <code>book:&#60;action&#62;</code> . So the  <code>list</code>  action requires the  <code>book:list</code>  permission, while  <code>show</code>  requires the  <code>book:show</code>  permission. As you've seen, you can make all actions available to a user by assigning the  <code>book:*</code>  or  <code>book</code>  permissions to him or her.<p class="paragraph"/>In other words, every controller action is protected by a permission requirement of the form  <code>&#60;controller&#62;:&#60;action&#62;</code> . That said, the plugin does treat the  <code>AuthController</code>  in such a way that it's impossible to protect it. That's because it makes no sense to require an authenticated user for the login page!<p class="paragraph"/><a name="Remember me?"></a><h3>Remember me?</h3><p class="paragraph"/>By default the plugin only grants access to an authenticated user, i.e. one that has explicitly logged in during the current session. You can allow access to both authenticated users and remembered users by setting <code>security.shiro.authc.required = false</code> in your <code>Config.groovy</code> file or by changing the line in <code>grails-app/conf/SecurityFilters.groovy</code> to <code>accessControl(auth: false)</code> .<p class="paragraph"/>The tags <code>&#60;shiro:isLoggedIn&#62;</code> and <code>&#60;shiro:authenticated&#62;</code> check for an authenticated user, the tag <code>&#60;shiro:user&#62;</code> checks for a known user (authenticated or remembered) and the tag <code>&#60;shiro:remembered&#62;</code> checks only for a remembered user.
<script type="text/javascript">
   if(myYUI.get('message')!=null) {
        myYUI.fade('message', {delay:3});
   }
</script>

                    </div>

<div id="faqTab">
                        



<div id="wikiLastUpdated">Last updated by mikesickler 2 years ago</div>
<div id="viewLinks" class="wikiLinks">
    

    <ul class="wikiActionMenu">
        
            <li>
                <a href="/plugin/faq-500/editWikiPage/faqTab" onclick="YAHOO.util.Connect.asyncRequest('GET', '/plugin/faq-500/editWikiPage/faqTab', {success: function(o){hideCommentPost();YAHOO.util.Dom.get('faqTab').innerHTML = o.responseText;}, failure: function(o){}}, null);return false;" class="actionIcon" action="editWikiPage" id="faq-500">
                    <img src="/static/drgakn823IcL4KeSlqigXNEYTBqSs0AKbVKJQH1z1yl.png" border="0" width="15" height="15" alt="Icon Edit" class="inlineIcon" />
                    <span>Edit</span>
                </a>
            </li>
        
        <li>
            <a href="/plugin/faq-500/infoWikiPage/faqTab" onclick="YAHOO.util.Connect.asyncRequest('GET', '/plugin/faq-500/infoWikiPage/faqTab', {success: function(o){YAHOO.util.Dom.get('faqTab').innerHTML = o.responseText;}, failure: function(o){}}, null);return false;" class="actionIcon" action="infoWikiPage" id="faq-500">
                <img src="/static/PnoLmQ9FQkQ1vYUqZ6BJ5yWRWKMaUJOz3Hzx68S9YBq.png" border="0" width="15" height="15" alt="Icon Edit" class="inlineIcon" />
                <span>View Info</span>
            </a>
        </li>
    </ul>
</div>






<strong class="bold">Q: Where can I enter a bug or a change request, etc?</strong><p class="paragraph"/>A: <a href="http://jira.codehaus.org/browse/GRAILSPLUGINS/component/14023" class="pageLink">JIRA space is here</a><p class="paragraph"/><strong class="bold">Q: Where are the release notes:</strong><p class="paragraph"/>A: <a href="http://www.grails.org/Shiro Release Notes" class="pageLink">Release notes are here</a><p class="paragraph"/><strong class="bold">Q: Where are the javadocs for org.apache.shiro.&#42;?</strong><p class="paragraph"/>A: <a href="http://cwiki.apache.org/SHIRO/download.html" class="pageLink">Download the source</a> and build the javadocs like this:
<div class="code"><pre>mvn javadoc:javadoc</pre></div><p class="paragraph"/><strong class="bold">Q: I get a  <code>LazyInitializationException</code>  when using the Shiro plugin with WebFlow. How do I fix it?</strong><p class="paragraph"/>A: WebFlow actions bypass the standard  <code>GrailsOpenSessionInViewInterceptor</code>  which means that if you access the database from within a Grails filter, you won't have a Hibernate session available. This is what happens when you use the  <code>accessControl {}</code>  syntax from a filter.<p class="paragraph"/>Probably the best solution is to execute the database access from within a transaction, either by using  <code>withTransaction</code>  inside your realm methods, or modifying the realm to delegate to a transactional service.
<script type="text/javascript">
   if(myYUI.get('message')!=null) {
        myYUI.fade('message', {delay:3});
   }
</script>

                    </div>

<div id="screenshotsTab">
                        



<div id="wikiLastUpdated">Last updated by admin 2 years ago</div>
<div id="viewLinks" class="wikiLinks">
    

    <ul class="wikiActionMenu">
        
            <li>
                <a href="/plugin/screenshots-500/editWikiPage/screenshotsTab" onclick="YAHOO.util.Connect.asyncRequest('GET', '/plugin/screenshots-500/editWikiPage/screenshotsTab', {success: function(o){hideCommentPost();YAHOO.util.Dom.get('screenshotsTab').innerHTML = o.responseText;}, failure: function(o){}}, null);return false;" class="actionIcon" action="editWikiPage" id="screenshots-500">
                    <img src="/static/drgakn823IcL4KeSlqigXNEYTBqSs0AKbVKJQH1z1yl.png" border="0" width="15" height="15" alt="Icon Edit" class="inlineIcon" />
                    <span>Edit</span>
                </a>
            </li>
        
        <li>
            <a href="/plugin/screenshots-500/infoWikiPage/screenshotsTab" onclick="YAHOO.util.Connect.asyncRequest('GET', '/plugin/screenshots-500/infoWikiPage/screenshotsTab', {success: function(o){YAHOO.util.Dom.get('screenshotsTab').innerHTML = o.responseText;}, failure: function(o){}}, null);return false;" class="actionIcon" action="infoWikiPage" id="screenshots-500">
                <img src="/static/PnoLmQ9FQkQ1vYUqZ6BJ5yWRWKMaUJOz3Hzx68S9YBq.png" border="0" width="15" height="15" alt="Icon Edit" class="inlineIcon" />
                <span>View Info</span>
            </a>
        </li>
    </ul>
</div>







<script type="text/javascript">
   if(myYUI.get('message')!=null) {
        myYUI.fade('message', {delay:3});
   }
</script>

                    </div>

            </div>
        </div>
        <script type="text/javascript">
            GRAILSUI.tabView_gui_fa6cc9bc44379aba5dc805b1baf53e87 = new YAHOO.widget.TabView('tabView_gui_fa6cc9bc44379aba5dc805b1baf53e87');
        </script>
                
    </div>


                    <div class="pluginBoxBottom"></div>
                    <div id="previewContainer" class="previewPane" style="display:none;">
    <div id="closePreview"><a href="#" onclick="hidePreview();"><img src="/static/hDJsm4ken9OT06aDDvH8zaXcH13K42QLdmmqCi3xnVK.png" class="inlineIcon" width="15" height="15" border="0" alt="Icon Cancel" /> Close</a></div>
    <div id="previewPane" style="margin:10px; "></div>
</div>
                </div>	
            </div>		
	</div>
    </div>


            </div>
        </div>
    </div>

    <div id="btmSectionGraphicsWrapper">
        <div id="mountainLeft"></div>
        <div id="knight"></div>
        <div id="mountainRight"></div>
        <div id="castle"></div>
    </div>

    <div id="footer">
    <div align="center">
        <div class="innerFooter">
            <a href="http://contegix.com/"><img src="/static/kyk1IIgLbhsHB7QxrDRoVw08G2anuhJvcSDQnDAEyu9.jpg" alt="Hosted by Contegix" /></a>
            <a href="http://www.jfrog.org/">
                <img src="/static/tp9jPkd06Rppu6vxoTrYPMRYtbkXrLCGoLCIAGjMaBW.png" class="artifactory" alt="Artifactory logo" title="In association with JFrog" />
            </a>
	
            <a href="http://twitter.com/grailsframework"><div class="twitter"></div></a>
            <p>
            <a href="http://www.vmware.com/help/legal.html">Terms of Use</a> |
            <a href="http://www.vmware.com/help/privacy.html">Privacy</a>
            &nbsp;&nbsp;&nbsp;&nbsp;&copy; Copyright 2009-2011 SpringSource.<br/>All Rights Reserved.
            </p>
        </div><!-- innerFooter -->
    </div><!-- center -->
</div><!-- footer -->


    
    <script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-2728886-12");
pageTracker._trackPageview();
} catch(err) {}
</script>

    
    <script type="text/javascript">
    var dmp = new diff_match_patch();

    function hideCommentPost() {
        YAHOO.util.Dom.addClass('postComment', 'hidden');
    }
    function showCommentPost() {
        YAHOO.util.Dom.removeClass('postComment', 'hidden');
    }

    function showDiff() {


        var text1 = myYUI.get("text1").innerHTML
        var text2 = myYUI.get("text2").innerHTML

        var d = dmp.diff_main(text1, text2);
        dmp.diff_cleanupSemantic(d);
        var ds = dmp.diff_prettyHtml(d);

        myYUI.get('diffOutputDiv').innerHTML = ds;

        myYUI.appear('diffOutputDiv')
    }

    function hidePreview() {
        myYUI.fade('previewContainer')
    }
    function showPreview() {
        myYUI.appear('previewContainer')
    }

function fadeMessages() {
    if(myYUI.get("errors")!=null) {
        myYUI.fade("errors", 5);
    }
    if(myYUI.get("message")!=null) {
        myYUI.fade("message", 10);
    }
}

function addJsClass() {
    var classes = document.body.className.split(" ");
	if (classes.length == 1 && classes[0] == "") {
		classes = ["js"];
	}
	else {
		classes.push("js");
	}
    document.body.className = classes.join(" ");
}
    </script>
</body>
</html>


